var thisPerson;
var thisVote, thisQuestVote;

var toProposal, toVote, toVoteResult, toQuest, toQuestVoteResult, toAssassination, toEndGame, toAssassinationEndGame;
var renderInfoBlock, loyalTritonInfo, pelleasInfo, neptuneInfo, legionInfo, panInfo, colorQuestCircles;
var startGame, proposeQuest, castVote, waitForVotes, tallyVotes, castQuestVote, waitForQuestVotes, tallyQuestVotes, assassinateNeptune;
var getGoodPlayers, updatePlayerList, randomizeOrder, setupGoodCharacters, setupBadCharacters, getEnabledParticipants;

gapi.hangout.onApiReady.add(function(eventObj){

// Event functions
toProposal = function(eventObj){
	gapi.hangout.data.onStateChanged.remove(toProposal);
	document.getElementById("lobby_div").style.display = "none";
	
	var state = eventObj.state;
	var proposer = parseInt(state.proposer);
	var proposerName = JSON.parse(state.playerList)[proposer];
	
	var currentQuest = parseInt(state.currentQuest);
	var questPlayerNum = JSON.parse(state.questPlayerNum)[currentQuest-1];
	
	if(currentQuest > 1){
		var prevStatusText = document.getElementById("prevstatus_text");
		prevStatusText.rows = document.getElementById("status_text").rows;
		prevStatusText.value = document.getElementById("status_text").value;
		document.getElementById("prevstatus_div").style.display = "block";
	}
	
	var statusText = document.getElementById("status_text");
	statusText.rows = 2;
	
	var playerList = JSON.parse(state.playerList);
	var checkBox, checkBoxLabel;
	
	for(var n = 0; n < 10; n++){
		checkBox = document.getElementById("check_" + (n+1).toString());
		checkBoxLabel = document.getElementById("checklabel_" + (n+1).toString());
		checkBox.checked = false;
		
		if(n < playerList.length){
			checkBox.style.display = "inline";
			checkBoxLabel.innerHTML = playerList[n];
		}
		else{
			checkBox.style.display = "none";
		}
	}
	
	if(thisPerson == proposerName){
		statusText.value = "You must propose a quest of " + questPlayerNum + " from the following group:";
		document.getElementById("proposal_div").style.display = "block";
	}
	else{
		statusText.value = proposerName + " is proposing a quest of " + questPlayerNum + " people.";
		document.getElementById("status_div").style.display = "block";
	}
	
	document.getElementById("status_div").style.display = "block";
	
	gapi.hangout.data.onStateChanged.add(toVote);
}

toVote = function(eventObj){
	gapi.hangout.data.onStateChanged.remove(toVote);
	document.getElementById("proposal_div").style.display = "none";
	
	var questPlayers = JSON.parse(eventObj.state.questPlayers);
	var proposerName = JSON.parse(eventObj.state.playerList)[parseInt(eventObj.state.proposer)];
	
	document.getElementById("prevstatus_div").style.display = "none";
	
	var statusText = document.getElementById("status_text");
	statusText.rows = questPlayers.length + 3;
	
	if(thisPerson == proposerName){
		statusText.value = "You have proposed the following quest:\n\n"
	}
	else{
		statusText.value = proposerName + " has proposed the following quest:\n\n"
	}
	
	for(var n = 0; n < questPlayers.length; n++){
		statusText.value += questPlayers[n];
		
		if(n < questPlayers.length - 1){
			statusText.value += "\n";
		}
	}
	
	document.getElementById("vote_div").style.display = "block";
	gapi.hangout.data.onStateChanged.add(toVoteResult);
};

toVoteResult = function(eventObj){
	var voteResult = JSON.parse(eventObj.state.voteResult);
	
	if(voteResult.indexOf(null) >= 0){
		return;
	}
	
	gapi.hangout.data.onStateChanged.remove(toVoteResult);
	var questApproved = JSON.parse(eventObj.state.questApproved);
	var voteResult = JSON.parse(eventObj.state.voteResult);
	
	var playerList = JSON.parse(eventObj.state.playerList);
	var statusText = document.getElementById("status_text");
	
	statusText.rows = 1 + playerList.length;
	statusText.value = "";
	for(n = 0; n < playerList.length; n++){
		statusText.value += playerList[n] + " voted to ";
		
		if(voteResult[n] == 1){
			statusText.value += "approve.";
		}
		else{
			statusText.value += "reject.";
		}
		
		if(n < playerList.length - 1){
			statusText.value += "\n";
		}
	}
	
	var numApprove = 0, numReject = 0;
		
	for(var n = 0; n < voteResult.length; n++){
		if(voteResult[n] == 1){
			numApprove++;
		}
		else{
			numReject++;
		}
	}
	
	if(questApproved){
		statusText.value = "The quest was approved " + numApprove + " to " + numReject + ".\n\n" + statusText.value;
		toQuest(eventObj);
	}
	else{
		statusText.value = "The quest was rejected " + numReject + " to " + numApprove + ".\n\n" + statusText.value;
		toProposal(eventObj);
	}
};

toQuest = function(eventObj){
	var questPlayers = JSON.parse(eventObj.state.questPlayers);
	var playerList = JSON.parse(eventObj.state.playerList);
	var characters = JSON.parse(eventObj.state.characters);
	
	var statusText = document.getElementById("status_text");
	statusText.rows += 3;
	
	if(questPlayers.indexOf(thisPerson) >= 0){
		var playerCharacter = characters[playerList.indexOf(thisPerson)];
	
		if(playerCharacter == "Loyal Triton" || playerCharacter == "Pelleas" || playerCharacter == "Neptune"){
			document.getElementById("fail_button").style.visibility = "hidden";
		}
		else{
			document.getElementById("fail_button").style.visibility = "visible";
		}
	
		document.getElementById("quest_div").style.display = "block";
		statusText.value = statusText.value + "\n\nDecide on your action:";
	}
	else{
		statusText.value = statusText.value + "\n\nWaiting for quest results.";
	}
	
	gapi.hangout.data.onStateChanged.add(toQuestVoteResult);
};

toQuestVoteResult = function(eventObj){
	var questDecision = JSON.parse(eventObj.state.questDecision);
	
	if(questDecision.indexOf(null) >= 0){
		return;
	}
	
	var questOutcome = JSON.parse(eventObj.state.questOutcome);
	var pastQuestIndex = JSON.parse(eventObj.state.currentQuest)-2;
	var numFailVotes = 0;
	
	for(var n = 0; n < questDecision.length; n++){
		if(questDecision[n] == 0){
			numFailVotes++;
		}
	}
	
	var statusText = document.getElementById("status_text");
	statusText.rows = 1;
		
	if(questOutcome[pastQuestIndex] == 1){
		if(numFailVotes == 0){
			statusText.value = "The quest passed with 0 fail votes";
		}
		else{
			statusText.value = "The quest passed with 1 fail vote";
		}
	}
	else{
		if(numFailVotes == 1){
			statusText.value = "The quest failed with 1 fail vote";
		}
		else{
			statusText.value = "The quest failed with " + numFailVotes + " fail votes";
		}
	}
	
	var numPassed = 0, numFailed = 0;
	
	for(var n = 0; n < 5; n++){
		if(questOutcome[n] == 1){
			numPassed++;
		}
		
		if(questOutcome[n] == 0){
			numFailed++;
		}
	}
	
	if(numFailed == 3){
		toEndGame(eventObj, 0);
	}
	else if(numPassed == 3){
		gapi.hangout.data.onStateChanged.remove(toQuestVoteResult);
		toAssassination(eventObj);
	}
	else{	
		gapi.hangout.data.onStateChanged.remove(toQuestVoteResult);
		toProposal(eventObj);
	}
};

toAssassination = function(eventObj){
	gapi.hangout.data.onStateChanged.add(toAssassinationEndGame);

	var prevStatusText = document.getElementById("prevstatus_text");
	prevStatusText.rows = document.getElementById("status_text").rows;
	prevStatusText.value = document.getElementById("status_text").value;
	document.getElementById("prevstatus_div").style.display = "block";
	
	var playerList = JSON.parse(eventObj.state.playerList);
	var characters = JSON.parse(eventObj.state.characters);
	
	var theMercenary = playerList[characters.indexOf("Mercenary")];
	
	var statusText = document.getElementById("status_text");
	
	if(thisPerson == theMercenary){
		statusText.rows = 3;
		statusText.value = "You are the mercenary, if you correctly assassinate Neptune your team wins, choose wisely.";
		
		var goodPlayers = getGoodPlayers(playerList, characters);
		
		for(var n = 0; n < 6; n++){
			checkBox = document.getElementById("checkass_" + (n+1).toString());
			checkBoxLabel = document.getElementById("checkasslabel_" + (n+1).toString());
			checkBox.checked = false;
		
			if(n < goodPlayers.length){
				checkBox.style.display = "inline";
				checkBoxLabel.innerHTML = goodPlayers[n];
			}
			else{
				checkBox.style.display = "none";
			}
		}
		
		document.getElementById("assassination_div").style.display = "block";
	}
	else{
		statusText.rows = 3;
		statusText.value = theMercenary + " is the mercenary.  If evil correctly assassinates Neptune they triumph.";
	}
};

toEndGame = function(eventObj, victor){
	var prevStatusText = document.getElementById("prevstatus_text");
	prevStatusText.rows = document.getElementById("status_text").rows;
	prevStatusText.value = document.getElementById("status_text").value;
	document.getElementById("prevstatus_div").style.display = "block";

	var state = eventObj.state;
	var playerList = JSON.parse(state.playerList);
	var characters = JSON.parse(state.characters);
	
	var statusText = document.getElementById("status_text");
	statusText.rows = playerList.length + 3;
	
	if(victor == 0){
		statusText.value = "Atlantis has fallen, Kronos is victorious.\n\n";
	}
	else{
		statusText.value = "Atlantis is safe, Atlas has prevailed.\n\n";
	}
	
	for(var n = 0; n < playerList.length; n++){
		switch(characters[n]){
			case "Loyal Triton":
			case "Legion of Kronos":
				statusText.value += playerList[n] + " was a " + characters[n];
			break;
			case "Mercenary":
				statusText.value += playerList[n] + " was the " + characters[n];
			break;
			case "Neptune":
			case "Pelleas":
			case "Medusa":
			case "Kronos":
			case "Pan":
				statusText.value += playerList[n] + " was " + characters[n];
			break;
		}
		
		if(n < playerList.length-1){
			statusText.value += "\n";
		}
	}
};

toAssassinationEndGame = function(eventObj){
	document.getElementById("prevstatus_div").style.display = "none";
	gapi.hangout.data.onStateChanged.remove(toAssassinationEndGame);
	
	var state = eventObj.state;
	var playerList = JSON.parse(state.playerList);
	var characters = JSON.parse(state.characters);
	var target = state.target;
	var assassinationSucceeded = JSON.parse(state.assassinationSucceeded);
	
	var statusText = document.getElementById("status_text");
	statusText.rows = playerList.length + 6;
	statusText.value = target + " was chosen for assassination.\n\n";
	
	if(assassinationSucceeded){
		statusText.value += "Atlantis has fallen, Kronos is victorious.\n\n";
	}
	else{
		statusText.value += "Atlantis is safe, Atlas has prevailed.\n\n";
	}
	
	for(var n = 0; n < playerList.length; n++){
		switch(characters[n]){
			case "Loyal Triton":
			case "Legion of Kronos":
				statusText.value += playerList[n] + " was a " + characters[n];
			break;
			case "Mercenary":
				statusText.value += playerList[n] + " was the " + characters[n];
			break;
			case "Neptune":
			case "Pelleas":
			case "Medusa":
			case "Kronos":
			case "Pan":
				statusText.value += playerList[n] + " was " + characters[n];
			break;
		}
		
		if(n < playerList.length-1){
			statusText.value += "\n";
		}
	}
}

renderInfoBlock = function(eventObj){
	document.getElementById("info_div").style.display = "block";

	var playerList = JSON.parse(eventObj.state.playerList);
	var characters = JSON.parse(eventObj.state.characters);
	var specialCharacters = JSON.parse(eventObj.state.specialCharacters);
	var proposer = JSON.parse(eventObj.state.proposer);
	
	var thisPlayerIndex = playerList.indexOf(thisPerson);
	var thisCharacter = characters[thisPlayerIndex];
	
	switch(thisCharacter){
		case "Loyal Triton":
			loyalTritonInfo(playerList, proposer);
		break;
		case "Pelleas":
			pelleasInfo(playerList, characters, specialCharacters, proposer);
		break;
		case "Neptune":
			neptuneInfo(playerList, characters, proposer);
		break;
		case "Legion of Kronos":
		case "Mercenary":
		case "Medusa":
		case "Kronos":
			legionInfo(playerList, characters, thisCharacter, proposer);
		break;
		case "Pan":
			panInfo(playerList, proposer);
		break;
	}
	
	
	var questOutcome = JSON.parse(eventObj.state.questOutcome);
	var currentQuest = JSON.parse(eventObj.state.currentQuest);
	var currentVote = JSON.parse(eventObj.state.currentVote);
	var questPlayerNum = JSON.parse(eventObj.state.questPlayerNum);
	var failTolerance = JSON.parse(eventObj.state.failTolerance);
	var infoContext = document.getElementById("info_canvas").getContext("2d");
	
	colorQuestCircles(infoContext, questOutcome, currentQuest, currentVote, questPlayerNum, failTolerance);
};

loyalTritonInfo = function(playerList, proposer){
	var infoText = document.getElementById("info_text");
	infoText.rows = playerList.length + 4;
	infoText.value = "You are a Loyal Triton of Atlas\n\nYou know almost nothing\n\n";
	
	for(var n = 0; n < playerList.length; n++){
		if(n == proposer){
			infoText.value += "*" + playerList[n];
		}
		else{
			infoText.value += playerList[n];
		}
	
		if(n < playerList.length-1){
			infoText.value += "\n";
		}
	}
};

pelleasInfo = function(playerList, characters, specialCharacters, proposer){
	var infoText = document.getElementById("info_text");
	infoText.rows = playerList.length + 4;
	infoText.value = "You are Pelleas\n\n";
	
	var neptunePlayer = playerList[characters.indexOf("Neptune")];
	var hasMedusa = specialCharacters[1];
	
	if(hasMedusa){
		var medusaPlayer = playerList[characters.indexOf("Medusa")];
		var neptunePlayers = randomizeOrder([neptunePlayer, medusaPlayer]);
		infoText.value += neptunePlayers[0] + " or " + neptunePlayers[1] + " is Neptune.\n\n";
	}
	else{
		infoText.value += neptunePlayer + " is Neptune.\n\n";
	}
	
	for(var n = 0; n < playerList.length; n++){
		if(n == proposer){
			infoText.value += "*" + playerList[n];
		}
		else{
			infoText.value += playerList[n];
		}
	
		if(n < playerList.length-1){
			infoText.value += "\n";
		}
	}
};

neptuneInfo = function(playerList, characters, proposer){
	var infoText = document.getElementById("info_text");
	infoText.rows = playerList.length + 4;
	infoText.value = "You are Neptune\n\nYou know good and evil\n\n";
	
	for(var n = 0; n < playerList.length; n++){
		if(n == proposer){
			infoText.value += "*";
		}
	
		infoText.value += playerList[n];
		
		if(characters[n] == "Loyal Triton" || characters[n] == "Neptune" || characters[n] == "Pelleas"){
			infoText.value += " is loyal to Atlas";
		}
		else{
			infoText.value += " is loyal to Kronos";
		}
	
		if(n < playerList.length-1){
			infoText.value += "\n";
		}
	}
};

legionInfo = function(playerList, characters, thisCharacter, proposer){
	var infoText = document.getElementById("info_text");
	infoText.rows = playerList.length + 4;
	
	switch(thisCharacter){
		case "Legion of Kronos":
			infoText.value = "You are a Legion of Kronos\n\nYou know good and evil players\n\n";
		break;
		case "Mercenary":
			infoText.value = "You are the Mercenary\n\nYou choose the assassination target\n\n";
		break;
		case "Medusa":
			infoText.value = "You are Medusa\n\nYou appear as Neptune to Pelleas\n\n";
		break;
		case "Kronos":
			infoText.value = "You are Kronos\n\nYou appear to Neptune as loyal to Atlas\n\n";
		break;
	}
	
	for(var n = 0; n < playerList.length; n++){
		if(n == proposer){
			infoText.value += "*";
		}
	
		infoText.value += playerList[n];
		
		if(characters[n] == "Loyal Triton" || characters[n] == "Neptune" || characters[n] == "Pelleas"  || characters[n] == "Pan"){
			infoText.value += " is loyal to Atlas";
		}
		else{
			infoText.value += " is loyal to Kronos";
		}
	
		if(n < playerList.length-1){
			infoText.value += "\n";
		}
	}
};

panInfo = function(playerList, proposer){
	var infoText = document.getElementById("info_text");
	infoText.rows = playerList.length + 4;
	infoText.value = "You are Pan\n\nYou don't know the other evil players\n\n";
	
	for(var n = 0; n < playerList.length; n++){
		if(n == proposer){
			infoText.value += "*" + playerList[n];
		}
		else{
			infoText.value += playerList[n];
		}
	
		if(n < playerList.length){
			infoText.value += "\n";
		}
	}
};

colorQuestCircles = function(infoContext, questOutcome, currentQuest, currentVote, questPlayerNum, failTolerance){
	infoContext.fillStyle = "#1C1C1C";
	infoContext.fillRect(0, 0, 300, 60);

	for(var n = 0; n < 5; n++){
		if(questOutcome[n] == 1){
			//infoContext.fillStyle = "blue";
			infoContext.fillStyle = "#02A6A3";
		}
		else if(questOutcome[n] == 0){
			//infoContext.fillStyle = "red";
			infoContext.fillStyle = "#F25E4E";
		}
		else{
			//infoContext.fillStyle = "yellow";
			infoContext.fillStyle = "#DEC504";
		}
		
		infoContext.beginPath();
		infoContext.arc(30+n*60, 30, 30, 0, 2*Math.PI);
		infoContext.fill();
		
		infoContext.font = ("24px Verdana");
		infoContext.fillStyle = "black";
		
		if(failTolerance[n] == 0){
			infoContext.fillText(questPlayerNum[n].toString(), 30+n*60-8, 40);
		}
		else{
			infoContext.fillText(questPlayerNum[n].toString() + "*", 30+n*60-16, 40);
		}
		
		if(n == currentQuest-1){
			infoContext.font = ("12px Verdana");
			infoContext.fillText(currentVote.toString(), 30+n*60-4, 12);
		}
	}
};

// Button actions
startGame = function(){
	var checkBox, checkBoxLabel;
	var enabledParticipants = getEnabledParticipants();
	var numPlayers = enabledParticipants.length;
	
	/*if(numPlayers < 5){
		return;
	}*/
	
	var specialCharacters = document.getElementById("character_list");
	var hasPelleas = specialCharacters.pelleas_check.checked;
	var hasMedusa = specialCharacters.medusa_check.checked;
	var hasKronos = specialCharacters.kronos_check.checked;
	var hasPan = specialCharacters.pan_check.checked;
	
	var numGood, numBad, questPlayerNum, failTolerance;
	
	switch(numPlayers){
		case 2: //test case
			numGood = 1;
			numBad = 1;
			questPlayerNum = [1, 2, 2, 2, 2];
			failTolerance = [0, 1, 0, 1, 0];
			break;
		case 3: //test case
			numGood = 1;
			numBad = 2;
			questPlayerNum = [2, 2, 3, 2, 3];
			failTolerance = [0, 1, 0, 1, 0];
			break;
		case 5:
			numGood = 3;
			numBad = 2;
			questPlayerNum = [2, 3, 2, 3, 3];
			failTolerance = [0, 0, 0, 0, 0];
		break;
		case 6:
			numGood = 4;
			numBad = 2;
			questPlayerNum = [2, 3, 4, 3, 4];
			failTolerance = [0, 0, 0, 0, 0];
		break;
		case 7:
			numGood = 4;
			numBad = 3;
			questPlayerNum = [2, 3, 3, 4, 4];
			failTolerance = [0, 0, 0, 1, 0];
		break;
		case 8:
			numGood = 5;
			numBad = 3;
			questPlayerNum = [3, 4, 4, 5, 5];
			failTolerance = [0, 0, 0, 1, 0];
		break;
		case 9:
			numGood = 6;
			numBad = 3;
			questPlayerNum = [3, 4, 4, 5, 5];
			failTolerance = [0, 0, 0, 1, 0];
		break;
		case 10:
			numGood = 6;
			numBad = 4;
			questPlayerNum = [3, 4, 4, 5, 5];
			failTolerance = [0, 0, 0, 1, 0];
		break;
	}
	
	specialCharacters = JSON.stringify([hasPelleas, hasMedusa, hasKronos, hasPan]);
	var numSpecialBad = hasMedusa + hasKronos + hasPan;
	
	if (numSpecialBad > numBad-1){
		return;
	}
	
	var goodCharacters = setupGoodCharacters(numGood, hasPelleas);
	var badCharacters = setupBadCharacters(numBad, hasMedusa, hasKronos, hasPan);
	var characters = JSON.stringify(randomizeOrder(goodCharacters.concat(badCharacters)));
	var playerList = JSON.stringify(randomizeOrder(enabledParticipants));
	var questOutcome = JSON.stringify([-1, -1, -1, -1, -1]);
	
	questPlayerNum = JSON.stringify(questPlayerNum);
	failTolerance = JSON.stringify(failTolerance);
	numPlayers = numPlayers.toString();
	
	gapi.hangout.data.submitDelta({phase: "proposal", numPlayers: numPlayers, currentQuest: "1", currentVote: "1", questPlayerNum: questPlayerNum, failTolerance: failTolerance, proposer: "0", playerList: playerList, characters: characters, questOutcome: questOutcome, specialCharacters: specialCharacters});
};

proposeQuest = function(){
	var state = gapi.hangout.data.getState();
	var playerList = JSON.parse(state.playerList);
	var playerNum = playerList.length;
	var currentQuest = parseInt(state.currentQuest);
	var questPlayerNum = JSON.parse(state.questPlayerNum)[currentQuest-1];
	var proposedNum = 0;
	var questProposal = new Array(playerNum);
	var questPlayers = new Array();
	
	for(var n = 0; n < playerNum; n++){
		questProposal[n] = document.getElementById("check_" + (n+1).toString()).checked;
		
		if(questProposal[n]){
			proposedNum++;
			questPlayers.push(playerList[n]);
		}
	}
	
	if (proposedNum != questPlayerNum){
		return;
	}
	
	var voteResult = JSON.stringify(new Array(playerNum));
	gapi.hangout.data.submitDelta({phase: "vote", questPlayers: JSON.stringify(questPlayers), voteResult: voteResult});
};

castVote = function(vote){
	document.getElementById("vote_div").style.display = "none";
	
	var state = gapi.hangout.data.getState();
	var playerList = JSON.parse(state.playerList);
	var voteResult = JSON.parse(state.voteResult);
	
	var statusText = document.getElementById("status_text");
	statusText.rows = 2;
	statusText.value = "Waiting for other votes.";
	
	var thisPlayerIndex = playerList.indexOf(thisPerson);
	var proposerName = playerList[parseInt(state.proposer)];
	
	voteResult[thisPlayerIndex] = vote;
	
	if(thisPerson != proposerName){
		gapi.hangout.data.submitDelta({voteResult: JSON.stringify(voteResult)});
		return;
	}
	
	thisVote = vote;
	setTimeout(waitForVotes, 500);
};

waitForVotes = function(){
	var state = gapi.hangout.data.getState();
	var playerList = JSON.parse(state.playerList);
	var thisPlayerIndex = playerList.indexOf(thisPerson);
	var voteResult = JSON.parse(state.voteResult);
	
	voteResult[thisPlayerIndex] = thisVote;
	
	if(voteResult.indexOf(null) >= 0){
		setTimeout(waitForVotes, 500);
	}
	else{
		tallyVotes(state, voteResult);
	}
};

tallyVotes = function(state, voteResult){
	var numApprove = 0, numReject = 0, questApproved;
		
	for(var n = 0; n < voteResult.length; n++){
		if(voteResult[n] == 1){
			numApprove++;
		}
		else{
			numReject++;
		}
	}
	
	if(numApprove > numReject){
		questApproved = true;
		var questDecision = JSON.stringify(new Array(JSON.parse(state.questPlayers).length));
		gapi.hangout.data.submitDelta({phase: "quest", voteResult: JSON.stringify(voteResult), questApproved: JSON.stringify(questApproved), questDecision: questDecision});
	}
	else{
		questApproved = false;
		var proposer = (parseInt(state.proposer) + 1) % voteResult.length;
		var currentVote = parseInt(state.currentVote) + 1;
		
		if(currentVote == 6){
			var eventObj = {state: state};			
			toEndGame(eventObj, 0);
			return;
		}
		
		gapi.hangout.data.submitDelta({phase: "proposal", voteResult: JSON.stringify(voteResult), questApproved: JSON.stringify(questApproved), proposer: proposer.toString(), currentVote: currentVote.toString()});
	}
};

castQuestVote = function(questVote){
	document.getElementById("quest_div").style.display = "none";
	
	var state = gapi.hangout.data.getState();
	var questPlayers = JSON.parse(state.questPlayers);
	var questDecision = JSON.parse(state.questDecision);
	var playerList = JSON.parse(state.playerList);
	
	var statusText = document.getElementById("status_text");
	statusText.rows += 2;
	statusText.value += "\n\nWaiting for other votes.";

	var thisPlayerIndex = questPlayers.indexOf(thisPerson);
	questDecision[thisPlayerIndex] = questVote;
	
	if(thisPerson != questPlayers[0]){
		gapi.hangout.data.submitDelta({questDecision: JSON.stringify(questDecision)});
		return;
	}
	
	thisQuestVote = questVote;
	setTimeout(waitForQuestVotes, 500);
};

waitForQuestVotes = function(){
	var state = gapi.hangout.data.getState();
	var questPlayers = JSON.parse(state.questPlayers);
	var questDecision = JSON.parse(state.questDecision);
	var thisPlayerIndex = questPlayers.indexOf(thisPerson);
	
	questDecision[thisPlayerIndex] = thisQuestVote;
	
	if(questDecision.indexOf(null) >= 0){
		setTimeout(waitForQuestVotes, 500);
	}
	else{
		tallyQuestVotes(state, questDecision);
	}
};

tallyQuestVotes = function(state, questDecision){
	var numPass = 0, numFail = 0, questPassed;
	
	for(var n = 0; n < questDecision.length; n++){
		if(questDecision[n] == 1){
			numPass++;
		}
		else{
			numFail++;
		}
	}
	
	var currentQuest = JSON.parse(state.currentQuest);
	var failTolerance = JSON.parse(state.failTolerance)[currentQuest-1];
	var questOutcome = JSON.parse(state.questOutcome);
	
	if(numFail <= failTolerance){
		questOutcome[currentQuest-1] = 1;
	}
	else{
		questOutcome[currentQuest-1] = 0;
	}
	
	currentQuest++;
	var proposer = (parseInt(state.proposer) + 1) % JSON.parse(state.playerList).length;
	
	var numPassed = 0, numFailed = 0;
	
	for(var n = 0; n < 5; n++){
		if(questOutcome[n] == 1){
			numPassed++;
		}
		
		if(questOutcome[n] == 0){
			numFailed++;
		}
	}
	
	if(numPassed == 3){
		newPhase = "assassination";
	}
	else if(numFailed == 3){
		newPhase = "endgame";
	}
	else{
		newPhase = "proposal";
	}
	
	gapi.hangout.data.submitDelta({phase: newPhase, questDecision: JSON.stringify(questDecision), questOutcome: JSON.stringify(questOutcome), currentQuest: currentQuest.toString(), proposer: proposer.toString(), currentVote: "1"});
};

assassinateNeptune = function(){
	var state = gapi.hangout.data.getState();
	var playerList = JSON.parse(state.playerList);
	var characters = JSON.parse(state.characters);
	
	var goodPlayers = getGoodPlayers(playerList, characters);
	var assassinationChoice = new Array(goodPlayers.length);
	var assassinationNum = 0;
	
	for(var n = 0; n < goodPlayers.length; n++){
		assassinationChoice[n] = document.getElementById("checkass_" + (n+1).toString()).checked;
		
		if(assassinationChoice[n]){
			assassinationNum++;
		}
	}
	
	if (assassinationNum != 1){
		return;
	}
	
	document.getElementById("assassination_div").style.display = "none";
	
	var target = goodPlayers[assassinationChoice.indexOf(true)];
	var neptunePlayer = playerList[characters.indexOf("Neptune")];
	var assassinationSucceeded;
	
	if(target == neptunePlayer){
		assassinationSucceeded = true;
	}
	else{
		assassinationSucceeded = false;
	}
	
	gapi.hangout.data.submitDelta({phase: "endgame", assassinationSucceeded: JSON.stringify(assassinationSucceeded), target: target});
}

// Utility functions
getGoodPlayers = function(playerList, characters){
	var goodPlayers = new Array();

	for(var n = 0; n < playerList.length; n++){
		if(characters[n] == "Loyal Triton" || characters[n] == "Pelleas" || characters[n] == "Neptune"){
			goodPlayers.push(playerList[n]);
		}
	}
	
	return(goodPlayers);
};

updatePlayerList = function(){
	var enabledParticipants = getEnabledParticipants();
	var playerList = document.getElementById("player_list");
	
	playerList.value = "";
	
	if (enabledParticipants == null){
		playerList.rows = 1;
		return;
	}
	else{
		playerList.rows = enabledParticipants.length;
	
		for (var n = 0; n < enabledParticipants.length; n++){
			playerList.value += enabledParticipants[n];
			
			if(n < enabledParticipants.length - 1){
				playerList.value += "\n";
			}
		}
	}
};

randomizeOrder = function(obj){
	var num = obj.length;
	var randomOrder = new Array(num);
	var randomObj = new Array(num);
	var maxVal;
	
	for (var n = 0; n < num; n++){
		randomOrder[n] = Math.random();
	}
	
	for (var m = 0; m < num; m++){
		maxVal = Math.max.apply(Math, randomOrder);
	
		for (n = 0; n < num; n++){
			if(randomOrder[n] == maxVal){
				randomObj[m] = obj[n];
				randomOrder[n] = -1;
			}
		}
	}
	
	return(randomObj);
};

setupGoodCharacters = function(numGood, hasPelleas){
	var goodCharacters = new Array();
	goodCharacters.push("Neptune");
	if(hasPelleas){
		goodCharacters.push("Pelleas");
	}
	
	for(var n = goodCharacters.length; n < numGood; n++){
		goodCharacters.push("Loyal Triton");
	}
	
	return(goodCharacters);
};

setupBadCharacters = function(numBad, hasMedusa, hasKronos, hasPan){
	var badCharacters = new Array();
	badCharacters.push("Mercenary");
	if(hasMedusa){
		badCharacters.push("Medusa");
	}
	if(hasKronos){
		badCharacters.push("Kronos");
	}
	if(hasPan){
		badCharacters.push("Pan");
	}
	
	for(var n = badCharacters.length; n < numBad; n++){
		badCharacters.push("Legion of Kronos");
	}
	
	return(badCharacters);
};

getEnabledParticipants = function(){
	var enabledParticipantsList = gapi.hangout.getEnabledParticipants();
	var numEnabledParticipants = enabledParticipantsList.length;
	
	if (numEnabledParticipants == 0)
		return (null);
	
	var enabledParticipants = new Array(numEnabledParticipants);
	
	for (var n = 0; n < numEnabledParticipants; n++){
		enabledParticipants[n] = enabledParticipantsList[n].person.displayName;
	}
		
	return(enabledParticipants);
};

	//if (eventObj.isApiReady) {
		thisPerson = gapi.hangout.getLocalParticipant().person.displayName;
		
		var state = gapi.hangout.data.getState();
		
		if(state.hasOwnProperty("playerList")){
			var playerList = JSON.parse(state.playerList);
			var eventObj = {state: state};
			var phase = state.phase;
			
			if(playerList.indexOf(thisPerson) == -1){
				document.getElementById("lobby_div").style.display = "none";
				document.getElementById("prevstatus_div").style.display = "none";
				document.getElementById("status_div").style.display = "none";
				document.getElementById("proposal_div").style.display = "none";
				document.getElementById("vote_div").style.display = "none";
				document.getElementById("quest_div").style.display = "none";
				document.getElementById("assassination_div").style.display = "none";
				document.getElementById("info_div").style.display = "block";
				document.getElementById("info_div").value = "Game is going on without you";
			}		
			else{
				document.getElementById("status_div").style.display = "block";
				document.getElementById("info_div").style.display = "block";
				document.getElementById("lobby_div").style.display = "none";
				gapi.hangout.data.onStateChanged.add(renderInfoBlock);
				renderInfoBlock(eventObj);
				
				switch(phase){
					case "proposal":
						toProposal(eventObj);
					break;
					case "vote":
						toVote(eventObj);
					break;
					case "quest":
						toQuest(eventObj);
					break;
					case "assassination":
						toAssassination(eventObj);
					break;
					case "endgame":
						toEndGame(eventObj);
					break;
				}
			}
		}
		else{
			gapi.hangout.onEnabledParticipantsChanged.add(updatePlayerList);
			gapi.hangout.data.onStateChanged.add(renderInfoBlock);
			gapi.hangout.data.onStateChanged.add(toProposal);
			updatePlayerList();
		}
	//}
});